package org.sagitta.httprpc;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ServiceConfig {
	private String controllerPackage;
	private String factoryClass;
	private String getForward;
	private Map<String, String> adaptorParameters;
	private static final Log log = LogFactory.getLog(ServiceConfig.class);
	private static final String DEFAULTADAPTORFACTORY = "org.sagitta.httprpc.json.adaptor.JSONAdaptorFactory";

	public ServiceConfig() {
		super();
		adaptorParameters = new HashMap<String, String>();
	}

	public void initializeConfiguriation(String path) throws Exception {
		InputStream is = new FileInputStream(path + "/minirpc-config.xml");
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(is);
		Element root = doc.getDocumentElement();
		parseControllerPackage(root);
		parseAdaptorFactory(root);
		parseGetForward(root);

	}

	private void parseControllerPackage(Element root) {
		NodeList nodes = root.getElementsByTagName("controller");
		if (nodes.getLength() > 0) {
			Element element = (Element)nodes.item(0);
			controllerPackage = element.getTextContent();
			if (log.isDebugEnabled()) {
				log.debug("The controller package is " + controllerPackage);
			}
		}
	}

	private void parseGetForward(Element root) {
		NodeList nodes = root.getElementsByTagName("getForward");
		if (nodes.getLength() > 0) {
			Element element = (Element)nodes.item(0);
			getForward = element.getTextContent();
			if (log.isDebugEnabled()) {
				log.debug("The get method will forward to the " + controllerPackage);
			}
		}
	}

	private void parseAdaptorFactory(Element root) {
		NodeList nodes = root.getElementsByTagName("adaptor");
		if (nodes.getLength() > 0) {
			Node node = nodes.item(0);
			Element e = (Element) node;
			this.factoryClass = e.getAttribute("factory");
			if (log.isDebugEnabled()) {
				log.debug("The adaptor factory is " + factoryClass);
			}
			parseFactoryParameters(e.getElementsByTagName("param"));
		}
	}

	private void parseFactoryParameters(NodeList paramNodes) {
		this.adaptorParameters.clear();
		for (int i = 0; i < paramNodes.getLength(); i++) {
			Node node = paramNodes.item(i);
			Element e = (Element) node;
			String key = e.getAttribute("name");
			String value = e.getAttribute("value");
			this.adaptorParameters.put(key, value);
			if (log.isDebugEnabled()) {
				log.debug("The adaptor factory parameter " + key + " = " + value);
			}
		}

	}

	public String getControllerPackage() {
		return controllerPackage;
	}

	public String getFactoryClass() {
		return factoryClass != null ? factoryClass : DEFAULTADAPTORFACTORY;
	}

	public Map<String, String> getAdaptorParameters() {
		return adaptorParameters;
	}

	public String getGetForward() {
		return getForward;
	}

}
